package Cn.Sarkar.MMS.WebAPI

import Cn.Sarkar.Entities.Common.ConnectionPool
import Cn.Sarkar.Entities.MMS.ToJsonEntities.JMMSWebServerStatus
import Cn.Sarkar.EntityDream.CoreEngine.RDBMS.Core.Extensions.createNewTables
import Cn.Sarkar.EntityDream.CoreEngine.RDBMS.MySql.createDataBaseIfNotExists
import Cn.Sarkar.MMS.Entities.DataSources.IDataSource
import Cn.Sarkar.MMS.Entities.DataSources.IDataSource.Companion.dataBaseConfig
import Cn.Sarkar.MMS.Entities.DataSources.IDataSource.Companion.isTablesExists
import Cn.Sarkar.MMS.Entities.DataSources.Sources.MySqlDataSource
import Cn.Sarkar.MMS.WebAPI.ToJsonEntites.JCreateDataBase
import Cn.Sarkar.ResponseModels.success
import io.ktor.locations.Location
import io.ktor.locations.location
import io.ktor.locations.put
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import io.ktor.routing.get
import io.ktor.routing.put
import jdk.nashorn.internal.ir.CatchNode
import java.sql.DriverManager


fun Route.useWebServerStatusController() {
    @Location("WebServer")
    class WebServer

    location<WebServer> {

        get("Status") {
            val config = IDataSource.dataBaseConfig
            val data = JMMSWebServerStatus().apply {
                databaseInitialized = false
                currentDataBase.apply {
                    database = config.database
                    driverClass = config.driverClass
                    initialPoolSize = config.initialPoolSize
                    jdbcUrl = config.jdbcUrl
                    maxPoolSize = config.maxPoolSize
                    minPoolSize = config.minPoolSize
                    userName = config.userName
                    password = "********"
                    metaData.apply {
                        productName = ""
                        productVersion = ""
                        driverName = ""
                        driverVersion = ""
                    }
                }
            }
            try {
                IDataSource.openAndAutoClose(ConnectionPool(IDataSource.loadNewConfig().apply {
                    retryAttemps = 0
                    initialPoolSize = 1
                    maxPoolSize = 1
                    minPoolSize = 1
                })) {
                    val meta = it.connection.metaData
                    it.connection.metaData
                    data.apply {
                        databaseInitialized = IDataSource.isTablesExists
                        currentDataBase.metaData.apply {
                            productName = meta.databaseProductName
                            productVersion = meta.databaseProductVersion
                            driverName = meta.driverName
                            driverVersion = meta.driverVersion

                        }
                    }

                }
            } catch (exception: Exception) {

            }

            context.respond(data)
        }

        put("CreateTables") {
            IDataSource.openAndAutoClose { db ->
                success {
                    if (!isTablesExists) db.createNewTables()
                }
            }

        }

        get("AvailableDataBases") {
            context.respond(listOf(
                    ConnectionPool.Configuration(
                            database = "MySql",
                            driverClass = "com.mysql.jdbc.Driver",
                            userName = "root",
                            password = "********",
                            maxPoolSize = 15,
                            minPoolSize = 5,
                            initialPoolSize = 10,
                            jdbcUrl = "jdbc:mysql://127.0.0.1:3306/SarkarMMS",
                            requiredPassword = true
                    ),
                    ConnectionPool.Configuration(
                            database = "SQLite",
                            driverClass = "org.sqlite.JDBC",
                            userName = "not required",
                            password = "not required",
                            maxPoolSize = 5,
                            minPoolSize = 3,
                            initialPoolSize = 4,
                            jdbcUrl = "jdbc:sqlite:SarkarMMS.db",
                            requiredPassword = false
                    )
            ))
        }

        put("SetDataBaseConfig") {
            success {
                val config = context.receive<ConnectionPool.Configuration>()

                val driver = Class.forName(config.driverClass)

                val con = DriverManager.getConnection(config.jdbcUrl, config.userName, config.password)



                con.close()
                IDataSource.dataBaseConfig = config
            }
        }

        put("CreateDataBase") {
            success {
                val config = context.receive<JCreateDataBase>()

                when (config.connection.database.toLowerCase()) {
                    "mysql" -> {
                        val driver = Class.forName(config.connection.driverClass)
                        val con = DriverManager.getConnection(config.connection.jdbcUrl, config.connection.userName, config.connection.password)

                        createDataBaseIfNotExists(con, config.databaseName)
                        if (!con.isClosed) con.close()
                    }
                }

            }
        }
    }
}